<!DOCTYPE html>
<html>
<head>
    <title>Circuit Diagram 4.29.1</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="circuitCanvas" width="800" height="450"></canvas>
    <script>
        const canvas = document.getElementById('circuitCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.lineWidth = 2;
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.font = '22px Times New Roman';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // --- Helper Functions ---

        // Draws a vertical resistor
        function drawResistorV(x, y_center, label, label_pos) {
            const w = 20;
            const h = 50;
            ctx.strokeRect(x - w / 2, y_center - h / 2, w, h);
            ctx.textAlign = label_pos;
            if (label_pos === 'left') {
                ctx.fillText(label, x - w / 2 - 5, y_center);
            } else { // right
                ctx.fillText(label, x + w / 2 + 5, y_center);
            }
        }

        // Draws a horizontal resistor
        function drawResistorH(x_center, y, label) {
            const w = 50;
            const h = 20;
            ctx.strokeRect(x_center - w / 2, y - h / 2, w, h);
            ctx.textAlign = 'center';
            ctx.fillText(label, x_center, y - h / 2 - 12);
        }
        
        // Draws a terminal (circle) with a label like V_n
        function drawTerminal(x, y, mainLabel, subLabel) {
            // Circle
            ctx.beginPath();
            ctx.arc(x, y, 4, 0, 2 * Math.PI);
            ctx.stroke();
            
            // Label
            const mainFont = '22px Times New Roman';
            const subFont = '16px Times New Roman';
            ctx.font = mainFont;
            ctx.textAlign = 'right';
            ctx.fillText(mainLabel, x - 5, y - 10);
            ctx.font = subFont;
            ctx.textAlign = 'left';
            ctx.fillText(subLabel, x - 3, y - 5);
            ctx.font = mainFont; // Reset font
        }

        // Draws a ground symbol
        function drawGround(x, y_start) {
             const y_end = y_start + 20;
             ctx.beginPath();
             ctx.moveTo(x, y_start);
             ctx.lineTo(x, y_end);
             ctx.moveTo(x - 15, y_end);
             ctx.lineTo(x + 15, y_end);
             ctx.moveTo(x - 10, y_end + 6);
             ctx.lineTo(x + 10, y_end + 6);
             ctx.moveTo(x - 5, y_end + 12);
             ctx.lineTo(x + 5, y_end + 12);
             ctx.stroke();
        }

        // --- Main Drawing Logic ---

        // Coordinates
        const y_rail = 200;
        const y_term = 100;
        const y_gnd = 320;

        const x_B = 680;
        const x_1 = 680; // same as B
        const x_2 = 560;
        const x_ellipsis_1 = 490;
        const x_ellipsis_2 = 410;
        const x_n_minus_1 = 340;
        const x_n = 220;
        const x_A = 220; // same as n

        // --- Draw Rightmost Branch (V1, Node B) ---
        drawTerminal(x_1, y_term, 'V', '1');
        ctx.beginPath();
        ctx.moveTo(x_1, y_term);
        ctx.lineTo(x_1, 145);
        ctx.moveTo(x_1, 195);
        ctx.lineTo(x_1, y_rail);
        ctx.stroke();
        drawResistorV(x_1, 170, '2 Ω', 'right');
        
        ctx.textAlign = 'center';
        ctx.fillText('B', x_B, y_rail + 25);

        ctx.beginPath();
        ctx.moveTo(x_B, y_rail);
        ctx.lineTo(x_B, 245);
        ctx.moveTo(x_B, 295);
        ctx.lineTo(x_B, y_gnd);
        ctx.stroke();
        drawResistorV(x_B, 270, '2 Ω', 'right');
        drawGround(x_B, y_gnd);

        // --- Draw Branch 2 (V2) ---
        drawTerminal(x_2, y_term, 'V', '2');
        ctx.beginPath();
        ctx.moveTo(x_2, y_term);
        ctx.lineTo(x_2, 145);
        ctx.moveTo(x_2, 195);
        ctx.lineTo(x_2, y_rail);
        ctx.stroke();
        drawResistorV(x_2, 170, '2 Ω', 'right');

        // --- Draw connection B to 2 ---
        const x_h_res_12 = (x_1 + x_2) / 2;
        ctx.beginPath();
        ctx.moveTo(x_1, y_rail);
        ctx.lineTo(x_h_res_12 + 25, y_rail);
        ctx.moveTo(x_h_res_12 - 25, y_rail);
        ctx.lineTo(x_2, y_rail);
        ctx.stroke();
        drawResistorH(x_h_res_12, y_rail, '1 Ω');

        // --- Draw Ellipsis Section ---
        const x_h_res_2e = (x_2 + x_ellipsis_1) / 2;
        ctx.beginPath();
        ctx.moveTo(x_2, y_rail);
        ctx.lineTo(x_h_res_2e + 25, y_rail);
        ctx.moveTo(x_h_res_2e - 25, y_rail);
        ctx.lineTo(x_ellipsis_1, y_rail);
        ctx.stroke();
        drawResistorH(x_h_res_2e, y_rail, '1 Ω');
        
        ctx.font = '30px Times New Roman';
        ctx.textAlign = 'center';
        ctx.fillText('...', (x_ellipsis_1 + x_ellipsis_2) / 2, y_rail);
        ctx.font = '22px Times New Roman'; // Reset font

        const x_h_res_e3 = (x_ellipsis_2 + x_n_minus_1) / 2;
        ctx.beginPath();
        ctx.moveTo(x_ellipsis_2, y_rail);
        ctx.lineTo(x_h_res_e3 + 25, y_rail);
        ctx.moveTo(x_h_res_e3 - 25, y_rail);
        ctx.lineTo(x_n_minus_1, y_rail);
        ctx.stroke();
        drawResistorH(x_h_res_e3, y_rail, '1 Ω');

        // --- Draw Branch n-1 ---
        drawTerminal(x_n_minus_1, y_term, 'V', 'n–1');
        ctx.beginPath();
        ctx.moveTo(x_n_minus_1, y_term);
        ctx.lineTo(x_n_minus_1, 145);
        ctx.moveTo(x_n_minus_1, 195);
        ctx.lineTo(x_n_minus_1, y_rail);
        ctx.stroke();
        drawResistorV(x_n_minus_1, 170, '2 Ω', 'right');

        // --- Draw connection n-1 to n ---
        const x_h_res_3n = (x_n_minus_1 + x_n) / 2;
        ctx.beginPath();
        ctx.moveTo(x_n_minus_1, y_rail);
        ctx.lineTo(x_h_res_3n + 25, y_rail);
        ctx.moveTo(x_h_res_3n - 25, y_rail);
        ctx.lineTo(x_n, y_rail);
        ctx.stroke();
        drawResistorH(x_h_res_3n, y_rail, '1 Ω');

        // --- Draw Leftmost Branch (Vn, Node A) ---
        drawTerminal(x_n, y_term, 'V', 'n');
        ctx.beginPath();
        ctx.moveTo(x_n, y_term);
        ctx.lineTo(x_n, 145);
        ctx.moveTo(x_n, 195);
        ctx.lineTo(x_n, y_rail);
        ctx.stroke();
        drawResistorV(x_n, 170, '2 Ω', 'left');

        ctx.textAlign = 'center';
        ctx.fillText('A', x_A, y_rail + 25);
        
        ctx.beginPath();
        ctx.moveTo(x_A, y_rail);
        ctx.lineTo(x_A, 245);
        ctx.moveTo(x_A, 295);
        ctx.lineTo(x_A, y_gnd);
        ctx.stroke();
        drawResistorV(x_A, 270, '2 Ω', 'left');
        drawGround(x_A, y_gnd);

        // --- Draw Caption ---
        ctx.font = '24px KaiTi'; // A common Chinese font
        ctx.textAlign = 'center';
        ctx.fillText('电图 4.29.1', canvas.width / 2, 400);

    </script>
</body>
</html>